#include "MC_include.h"
#include "gt911.h"
#include "gt911iic.h"
#include "touch.h"
#include <string.h>

#if 0
////电容触摸屏控制器
//_m_ctp_dev ctp_dev=
//{
//	GT911_Init,
//	GT911_Scan,
//	0,
//	0,
//	0,
//	0,
//	0,
//};

//向GT911写入一次数据
//reg:起始寄存器地址
//buf:数据缓缓存区
//len:写数据长度
//返回值:0,成功;1,失败.
u8 GT911_WR_Reg(u16 reg,u8 *buf,u8 len)
{
	u8 i;
	u8 ret=0;
	GT911_IIC_Start();	
 	GT911_IIC_Send_Byte(CT_CMD_WR);   	//发送写命令 	 
	GT911_IIC_Wait_Ack();
	GT911_IIC_Send_Byte(reg>>8);   	//发送高8位地址
	GT911_IIC_Wait_Ack(); 	 										  		   
	GT911_IIC_Send_Byte(reg&0XFF);   	//发送低8位地址
	GT911_IIC_Wait_Ack();  
	for(i=0;i<len;i++)
	{	   
    	GT911_IIC_Send_Byte(buf[i]);  	//发数据
		ret=GT911_IIC_Wait_Ack();
		if(ret)break;  
	}
    GT911_IIC_Stop();					//产生一个停止条件	    
	return ret; 
}
//从GT911读出一次数据
//reg:起始寄存器地址
//buf:数据缓缓存区
//len:读数据长度			  
void GT911_RD_Reg(u16 reg,u8 *buf,u8 len)
{
	u8 i;
 	GT911_IIC_Start();	
 	GT911_IIC_Send_Byte(CT_CMD_WR);   	//发送写命令 	 
	i=GT911_IIC_Wait_Ack();
 	GT911_IIC_Send_Byte(reg>>8);   	//发送高8位地址
	GT911_IIC_Wait_Ack(); 	 										  		   
 	GT911_IIC_Send_Byte(reg&0XFF);   	//发送低8位地址
	GT911_IIC_Wait_Ack();  
 	GT911_IIC_Start();  	 	   
	GT911_IIC_Send_Byte(CT_CMD_RD);    //发送读命令		   
	GT911_IIC_Wait_Ack();	   
	for(i=0;i<len;i++)
	{	   
    	buf[i]=GT911_IIC_Read_Byte(i==(len-1)?0:1); //发数据	  
	} 
    GT911_IIC_Stop();//产生一个停止条件	    
}
//GT911初始化程序
 void GT911_Init(void)
{
	
	GPIO_InitTypeDef GPIO_InitStructure;
	__GPIOI_CLK_ENABLE(); //GT811复位信号
	__GPIOH_CLK_ENABLE();  //GT811中断信号
	
    GPIO_InitStructure.Pin = GPIO_PIN_8;
    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStructure.Pull = GPIO_PULLUP;
    GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
    HAL_GPIO_Init(GPIOI, &GPIO_InitStructure);//GT811复位信号
	
    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStructure.Pull =GPIO_PULLUP;
    GPIO_InitStructure.Pin = GPIO_PIN_7;
    HAL_GPIO_Init(GPIOH, &GPIO_InitStructure);////GT811中断信号
	
    HAL_GPIO_WritePin(GPIOI,GPIO_PIN_8,GPIO_PIN_RESET); //输出低
	HAL_GPIO_WritePin(GPIOH,GPIO_PIN_7,GPIO_PIN_RESET); //输出低
	delay_us(120);
	HAL_GPIO_WritePin(GPIOI,GPIO_PIN_8,GPIO_PIN_SET);
	delay_ms(10);
	GPIO_InitStructure.Mode = GPIO_MODE_INPUT ;
    GPIO_InitStructure.Pull =GPIO_PULLUP;
    GPIO_InitStructure.Pin = GPIO_PIN_7;
    HAL_GPIO_Init(GPIOH, &GPIO_InitStructure);////GT811中断信号
 	GT911_IIC_Init();								//电容触摸屏部分,IIC初始化

}
// 函数：触摸扫描
//	说明：在程序里周期性的调用该函数，用以检测触摸操作
//
u8 GT911_Scan()
{
	u8  teoporary[1];	
 	u8  touchData[2 + 8 * 5 ]; //用于存储触摸数据
    u8 num;
	u8 buf[1];
	buf[0]=0;
	
	GT911_RD_Reg (0x8056,teoporary,1);	//读数据
	GT911_RD_Reg (0x814E,touchData,2 + 8 * 5);	//读数据
    GT911_WR_Reg (0x814E,buf,1);	//	清除触摸芯片的寄存器标志位
	num = touchData[0] & 0x0f;	//取当前的触摸点数
	
	if ( (num >= 1) && (num <=5) ) //当触摸数在 1-5 之间时
	{
		// 取相应的触摸坐标
		switch(num)
		{
			case 5:
			{
				tp_dev.x[4] = (touchData[5+32]<<8) | touchData[4+32]*800/1024;
				tp_dev.y[4] = (touchData[3+32]<<8) | touchData[2+32]*480/600;
                tp_dev.sta|=0x10;				
     		}
			case 4:
			{
				tp_dev.x[3] = (touchData[5+24]<<8) | touchData[4+24]*800/1024;
				tp_dev.y[3] = (touchData[3+24]<<8) | touchData[2+24]*480/600;
                tp_dev.sta|=0x08;				
			}
			case 3:
			{
				tp_dev.x[2] = (touchData[5+16]<<8) | touchData[4+16]*800/1024;
				tp_dev.y[2] = (touchData[3+16]<<8) | touchData[2+16]*480/600;
                tp_dev.sta|=0x04;				
			}
			case 2:
			{
				tp_dev.x[1] = (touchData[5+8]<<8) | touchData[4+8]*800/1024;
				tp_dev.y[1] = (touchData[3+8]<<8) | touchData[2+8]*480/600;			
				tp_dev.sta|=0x02;
			}
			case 1:
			{
				tp_dev.x[0] = ((touchData[5]<<8) | touchData[4])*800/1024;
				tp_dev.y[0] = ((touchData[3]<<8) | touchData[2])*480/600;
				tp_dev.sta|=0x01;
			}
			default:break;
		}	
		tp_dev.sta|=0x80;	//标记按键按下		
		return	SUCCESS ;	
	}

	else                       
	{
		tp_dev.sta=0;	//标记按键松开	
		return	ERROR ;		
	}
	
}

#else


//GT911配置参数表
//第一个字节为版本号(0X60),必须保证新的版本号大于等于GT911内部
//flash原有版本号,才会更新配置.
const u8 GT911_CFG_TBL[]=
{ 
	0X60,0XE0,0X01,0X20,0X03,0X05,0X35,0X00,0X02,0X08,
	0X1E,0X08,0X50,0X3C,0X0F,0X05,0X00,0X00,0XFF,0X67,
	0X50,0X00,0X00,0X18,0X1A,0X1E,0X14,0X89,0X28,0X0A,
	0X30,0X2E,0XBB,0X0A,0X03,0X00,0X00,0X02,0X33,0X1D,
	0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X32,0X00,0X00,
	0X2A,0X1C,0X5A,0X94,0XC5,0X02,0X07,0X00,0X00,0X00,
	0XB5,0X1F,0X00,0X90,0X28,0X00,0X77,0X32,0X00,0X62,
	0X3F,0X00,0X52,0X50,0X00,0X52,0X00,0X00,0X00,0X00,
	0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
	0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X0F,
	0X0F,0X03,0X06,0X10,0X42,0XF8,0X0F,0X14,0X00,0X00,
	0X00,0X00,0X1A,0X18,0X16,0X14,0X12,0X10,0X0E,0X0C,
	0X0A,0X08,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
	0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
	0X00,0X00,0X29,0X28,0X24,0X22,0X20,0X1F,0X1E,0X1D,
	0X0E,0X0C,0X0A,0X08,0X06,0X05,0X04,0X02,0X00,0XFF,
	0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
	0X00,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
	0XFF,0XFF,0XFF,0XFF,
};  
//发送GT911配置参数
//mode:0,参数不保存到flash
//     1,参数保存到flash
u8 GT911_Send_Cfg(u8 mode)
{
	u8 buf[2];
	u8 i=0;
	buf[0]=0;
	buf[1]=mode;	//是否写入到GT911 FLASH?  即是否掉电保存
	for(i=0;i<sizeof(GT911_CFG_TBL);i++)buf[0]+=GT911_CFG_TBL[i];//计算校验和
    buf[0]=(~buf[0])+1;
	GT911_WR_Reg(GT_CFGS_REG,(u8*)GT911_CFG_TBL,sizeof(GT911_CFG_TBL));//发送寄存器配置
	GT911_WR_Reg(GT_CHECK_REG,buf,2);//写入校验和,和配置更新标记
	return 0;
} 
//向GT911写入一次数据
//reg:起始寄存器地址
//buf:数据缓缓存区
//len:写数据长度
//返回值:0,成功;1,失败.
u8 GT911_WR_Reg(u16 reg,u8 *buf,u8 len)
{
	u8 i;
	u8 ret=0;
	GT911_IIC_Start();	
 	GT911_IIC_Send_Byte(GT_CMD_WR);   	//发送写命令 	 
	GT911_IIC_Wait_Ack();
	GT911_IIC_Send_Byte(reg>>8);   	//发送高8位地址
	GT911_IIC_Wait_Ack(); 	 										  		   
	GT911_IIC_Send_Byte(reg&0XFF);   	//发送低8位地址
	GT911_IIC_Wait_Ack();  
	for(i=0;i<len;i++)
	{	   
    	GT911_IIC_Send_Byte(buf[i]);  	//发数据
		ret=GT911_IIC_Wait_Ack();
		if(ret)break;  
	}
    GT911_IIC_Stop();					//产生一个停止条件	    
	return ret; 
}
//从GT911读出一次数据
//reg:起始寄存器地址
//buf:数据缓缓存区
//len:读数据长度			  
void GT911_RD_Reg(u16 reg,u8 *buf,u8 len)
{
	u8 i; 
 	GT911_IIC_Start();	
 	GT911_IIC_Send_Byte(GT_CMD_WR);   //发送写命令 	 
	GT911_IIC_Wait_Ack();
 	GT911_IIC_Send_Byte(reg>>8);   	//发送高8位地址
	GT911_IIC_Wait_Ack(); 	 										  		   
 	GT911_IIC_Send_Byte(reg&0XFF);   	//发送低8位地址
	GT911_IIC_Wait_Ack();  
 	GT911_IIC_Start();  	 	   
	GT911_IIC_Send_Byte(GT_CMD_RD);   //发送读命令		   
	GT911_IIC_Wait_Ack();	   
	for(i=0;i<len;i++)
	{	   
    	buf[i]=GT911_IIC_Read_Byte(i==(len-1)?0:1); //发数据	  
	} 
    GT911_IIC_Stop();//产生一个停止条件    
} 
u8 temp[5]; 
//初始化GT911触摸屏
//返回值:0,初始化成功;1,初始化失败 
u8 GT911_Init(void)
{
	
	GPIO_InitTypeDef GPIO_Initure;
	
	__HAL_RCC_GPIOH_CLK_ENABLE();			//开启GPIOH时钟
	__HAL_RCC_GPIOI_CLK_ENABLE();			//开启GPIOI时钟
                
    GPIO_Initure.Pin = GPIO_PIN_8;
    GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_Initure.Pull = GPIO_PULLUP;
    GPIO_Initure.Speed = GPIO_SPEED_FAST;
    HAL_GPIO_Init(GPIOI, &GPIO_Initure);//GT811复位信号
	
    GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_Initure.Pull =GPIO_PULLUP;
    GPIO_Initure.Pin = GPIO_PIN_7;
    HAL_GPIO_Init(GPIOH, &GPIO_Initure);////GT811中断信号
	
	HAL_GPIO_WritePin(GPIOI,GPIO_PIN_8,GPIO_PIN_RESET); //输出低
	HAL_GPIO_WritePin(GPIOH,GPIO_PIN_7,GPIO_PIN_RESET); //输出低
	delay_us(120);
	HAL_GPIO_WritePin(GPIOI,GPIO_PIN_8,GPIO_PIN_SET);
	delay_ms(10);
	GPIO_Initure.Mode = GPIO_MODE_INPUT ;
    GPIO_Initure.Pull =GPIO_PULLUP;
    GPIO_Initure.Pin = GPIO_PIN_7;
    HAL_GPIO_Init(GPIOH, &GPIO_Initure);////GT811中断信号
 
	GT911_IIC_Init();      	//初始化电容屏的I2C总线  
	GT911_RD_Reg(GT_PID_REG,temp,4);//读取产品ID
	temp[4]=0;
	printf("CTP ID:%s\r\n",temp);	//打印ID
//	if(strcmp((char*)temp,"911")==0)//ID==911
//	{
		temp[0]=0X02;			
		GT911_WR_Reg(GT_CTRL_REG,temp,1);//软复位GT911
		GT911_RD_Reg(GT_CFGS_REG,temp,1);//读取GT_CFGS_REG寄存器
		if(temp[0]<0X60)//默认版本比较低,需要更新flash配置
		{
		//	printf("Default Ver:%d\r\n",temp[0]);
							if(lcddev.id==0X5510)GT911_Send_Cfg(1);//更新并保存配置
		}
		delay_ms(10);
		temp[0]=0X00;	 
		GT911_WR_Reg(GT_CTRL_REG,temp,1);//结束复位   
		return 0;
//	} 
	return 1;
}

const u16 GT911_TPX_TBL[5]={GT_TP1_REG,GT_TP2_REG,GT_TP3_REG,GT_TP4_REG,GT_TP5_REG};
//扫描触摸屏(采用查询方式)
//mode:0,正常扫描.
//返回值:当前触屏状态.
//0,触屏无触摸;1,触屏有触摸
u8 GT911_Scan()
{
	u8 mode;
	u8 buf[4];
	u8 i=0;
	u8 res=0;
	u8 temp;
	u8 tempsta;
 	static u8 t=0;//控制查询间隔,从而降低CPU占用率   
	t++;
	if((t%10)==0||t<10)//空闲时,每进入10次CTP_Scan函数才检测1次,从而节省CPU使用率
	{
		GT911_RD_Reg(GT_GSTID_REG,&mode,1);	//读取触摸点的状态  
 		if(mode&0X80&&((mode&0XF)<6))
		{
			temp=0;
			GT911_WR_Reg(GT_GSTID_REG,&temp,1);//清标志 			
		}		
		if((mode&0XF)&&((mode&0XF)<6))
		{
			temp=0XFF<<(mode&0XF);		//将点的个数转换为1的位数,匹配tp_dev.sta定义 
			tempsta=tp_dev.sta;			//保存当前的tp_dev.sta值
			tp_dev.sta=(~temp)|TP_PRES_DOWN; 
			tp_dev.x[4]=tp_dev.x[0];	//保存触点0的数据
			tp_dev.y[4]=tp_dev.y[0];
			for(i=0;i<5;i++)
			{
				if(tp_dev.sta&(1<<i))	//触摸有效?
				{
					GT911_RD_Reg(GT911_TPX_TBL[i],buf,4);	//读取XY坐标值
					tp_dev.x[i]=(((u16)buf[1]<<8)+buf[0])*800/1024;
                    tp_dev.y[i]=(((u16)buf[3]<<8)+buf[2])*480/600;
					//printf("x[%d]:%d,y[%d]:%d\r\n",i,tp_dev.x[i],i,tp_dev.y[i]);
				}			
			} 
			res=1;
			if(tp_dev.x[0]>lcddev.width||tp_dev.y[0]>lcddev.height)//非法数据(坐标超出了)
			{ 
				if((mode&0XF)>1)		//有其他点有数据,则复第二个触点的数据到第一个触点.
				{
					tp_dev.x[0]=tp_dev.x[1];
					tp_dev.y[0]=tp_dev.y[1];
					t=0;				//触发一次,则会最少连续监测10次,从而提高命中率
				}else					//非法数据,则忽略此次数据(还原原来的)  
				{
					tp_dev.x[0]=tp_dev.x[4];
					tp_dev.y[0]=tp_dev.y[4];
					mode=0X80;		
					tp_dev.sta=tempsta;	//恢复tp_dev.sta
				}
			}else t=0;					//触发一次,则会最少连续监测10次,从而提高命中率
		}
	}
	if((mode&0X8F)==0X80)//无触摸点按下
	{ 
		if(tp_dev.sta&TP_PRES_DOWN)	//之前是被按下的
		{
			tp_dev.sta&=~(1<<7);	//标记按键松开
		}else						//之前就没有被按下
		{ 
			tp_dev.x[0]=0;
			tp_dev.y[0]=0;
			tp_dev.sta&=0XE0;	//清除点有效标记	
		}	 
	} 	
	if(t>240)t=10;//重新从10开始计数
	return res;
}
 


#endif
